#include <types.h>
#include <Debug.h>
#include <FrameAllocator.h>
#include <Multiboot.h>

extern "C" dword _end;
dword Multiboot::MBLimit;

void Multiboot::Init(void *ptr) {
	MultibootHeader *hdr = (MultibootHeader *) ptr;

	struct MemoryMap *mmap;

	dputs("\nKernel cmdline: ");
	dputs((char *) hdr->cmdline);
	dputch('\n');

	dword base, len;
	for (mmap = (struct MemoryMap *) hdr->mmap_addr; (dword) mmap < hdr->mmap_addr + hdr->mmap_length; mmap = (MemoryMap *) ((dword) mmap + mmap->size + sizeof(mmap->size))) {
		/**
		 * If @type == 1 then the region is free to be used
		 */
		if (mmap->type == 1) {
			base = (((unsigned) mmap->base_addr_high << 16) | (unsigned) mmap->base_addr_low);
			len = ((unsigned) mmap->length_high << 16) | (unsigned) mmap->length_low;
			FrameAllocator::MarkFrames(base, len / 0x1000, false);
		}
	}

	MBLimit = (dword) &_end;

	/* Mark kernel and kernel modules frames as used */
	base = 0x00100000;
	len = MBLimit - base;
	FrameAllocator::MarkFrames(base, len / 0x1000, true);
	
	/* Mark IVT as used */
	FrameAllocator::MarkFrames(0, 1, true);
}

